#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "getop.h"

/* buffer for ungetch */
static char buf[BUFSIZE];
/* next free position in buf */
static int bufp = 0;

/* taken from "The C Programming Language" by Kernighan & Ritchie */
/* slightly modified */ 
/* getop: get next character or numeric operand */
static int getop(char * s);
/* get first character that is not a space */
static int gettoken(void);
/* taken from "The C Programming Language" by Kernighan & Ritchie */ 
static int getch(void);
/* taken from "The C Programming Language" by Kernighan & Ritchie */ 
static void ungetch(int);


/* read a double operand from stdin */
int 
getOperand(double * op)
{
	int ret;
	char buffer[BUFSIZE];
	
	if ((ret = getop(buffer)) == NUMBER)
		*op = atof(buffer);
	else 
		return 1;

	return 0;
} 

/* read a valid operator from stdin */
int 
getOperator(unsigned char * op)
{
	switch(gettoken())
	{
		case '+':	*op = ADD; break;
		case '-':	*op = SUB; break;
		case '*':	*op = MULT; break;
		case '/':	*op = DIV; break;
		default:	return 1;
	}

	return 0;
}

/* get first character that is not a space */
static int
gettoken(void)
{
	int c;
	
	while ((c = getch()) == ' ' || c == '\t' || c == '\n')
		;

	if (c == EOF)
		exit(0);
	else
		return c;
}

/* taken from "The C Programming Language" by Kernighan & Ritchie */
/* slightly modified to support negative numbers*/ 
/* getop: get next character or numeric operand */
static int 
getop(char * s)
{
	int i, c, sign = 0;
	
	while ((s[0] = c = getch()) == ' ' || c == '\t' || c == '\n')
		;
	s[1] = '\0';
	
	if (c == '+' || c == '-')
	{
		s[1] = c = getch();
		sign = 1;
	}		

	if (!isdigit(c) && c != '.')
	{
		if (c == EOF)
			exit(0);
		else
			return c;      /* not a number */
	}

	i = 0;
	if (sign)
		i++;

	if (isdigit(c))    /* collect integer part */
		while (i < BUFSIZE - 1 && isdigit(s[++i] = c = getch()))
			;
	if (c == '.')      /* collect fraction part */
		while (i < BUFSIZE - 1 && isdigit(s[++i] = c = getch()))
			;
	s[i] = '\0';
	if (c != EOF)
		ungetch(c);
	else
		exit(0);

	return NUMBER;
}

/* taken from "The C Programming Language" by Kernighan & Ritchie */ 
static int 
getch(void) /* get a (possibly pushed-back) character */
{
	return (bufp > 0) ? buf[--bufp] : getchar();
}

/* taken from "The C Programming Language" by Kernighan & Ritchie */ 
static void 
ungetch(int c)   /* push character back on input */
{
	if (bufp >= BUFSIZE)
		fprintf(stderr, "Client: ungetch: too many characters\n");
	else
		buf[bufp++] = c;
}


